package postgres

import (
	"context"
	"gorm.io/gorm"
	"manager/errors"
	"manager/model"
	"manager/model/entity"
	"manager/utils"
)

var Battery = &battery{}

type battery struct{}

// Create 创建
func (a *battery) Create(ctx context.Context, m *entity.Battery) (int64, error) {
	err := GetDB(ctx).Create(m).Error
	return m.Id, err
}

// Find 查找详情
func (a *battery) Find(ctx context.Context, in *model.BatteryInfoRequest) (*entity.Battery, error) {
	e := &entity.Battery{}

	q := GetDB(ctx).Model(&entity.Battery{})

	if in.Id > 0 {
		err := q.First(&e, in.Id).Error
		return e, err
	}

	count := 0

	if in.BatteryCode != nil {

		q = q.Where("battery_code like ?", in.BatteryCode)

		count++
	}

	if in.FirmwaresVersion != nil {

		q = q.Where("firmwares_version like ?", in.FirmwaresVersion)

		count++
	}

	if in.BatteryType != nil {

		q = q.Where("battery_type = ?", in.BatteryType)

		count++
	}

	if in.UpdatedAt != nil {

		q = q.Where("updated_at = ?", in.UpdatedAt)

		count++
	}

	if count == 0 {
		return e, errors.New("condition illegal")
	}

	err := q.First(&e).Error
	return e, err
}

// Update 更新
func (a *battery) Update(ctx context.Context, id int64, dict map[string]interface{}) error {
	return GetDB(ctx).Model(&entity.Battery{}).Where("id = ?", id).Updates(dict).Error
}

// Delete 删除
func (a *battery) Delete(ctx context.Context, id int64) error {
	return GetDB(ctx).Delete(&entity.Battery{}, id).Error
}

// BatteryInfoList 电池信息列表
func (a *battery) BatteryInfoList(ctx context.Context, batteryIds []int64) (total int, list []*model.BatteryData, err error) {
	if len(batteryIds) == 0 {
		return
	}

	err = GetDB(ctx).Model(&entity.Battery{}).Select("batterys.*,battery_types.id as battery_type_id,battery_types.name, battery_types.type,battery_types.supplier, battery_types.voltage, battery_types.version,"+
		" battery_types.capacity").Where("batterys.id in (?)", batteryIds).Joins("left join battery_types on battery_types.id = batterys.battery_type").Find(&list).Error
	total = len(list)
	return
}

// List 列表查询
func (a *battery) List(ctx context.Context, in *model.BatteryListRequest) (int, []*entity.Battery, error) {
	var (
		q        = GetDB(ctx).Model(&entity.Battery{})
		err      error
		total    int64
		batterys []*entity.Battery
	)

	if in.BatteryCode != nil {

		q = q.Where("battery_code like ?", utils.SqlLike(in.BatteryCode))

	}

	if in.FirmwaresVersion != nil {

		q = q.Where("firmwares_version like ?", in.FirmwaresVersion)

	}

	if in.BatteryType != nil {

		q = q.Where("battery_type = ?", in.BatteryType)

	}

	if in.UpdatedAt != nil {

		q = q.Where("updated_at = ?", in.UpdatedAt)

	}

	if err = q.Count(&total).Error; err != nil {
		return 0, nil, err
	}
	if err = q.Order("created_at desc").Limit(in.Size).Offset((in.Index - 1) * in.Size).Find(&batterys).Error; err != nil {
		return 0, nil, err
	}
	return int(total), batterys, nil
}

// ExecTransaction db事务执行
func (a *battery) ExecTransaction(ctx context.Context, callback func(ctx context.Context) error) error {
	return GetDB(ctx).Transaction(func(tx *gorm.DB) error {
		ctx = context.WithValue(ctx, DBCONTEXTKEY, tx)
		return callback(ctx)
	})
}
